package com.gitee.smalllog.server.client;

import com.gitee.smalllog.core.client.AbstractClient;
import com.gitee.smalllog.core.client.RedisClient;
import com.gitee.smalllog.core.constant.InitConfig;
import com.gitee.smalllog.core.constant.LogMessageConstant;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.StringUtils;

import java.time.ZoneId;

@Configuration
@Order(1)
public class ClientConfig implements InitializingBean {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ClientConfig.class);
    @Value("${smalllog.maxSendSize:5000}")
    public int maxSendSize = 5000;
    @Value("${smalllog.interval:100}")
    public int interval = 100;
    @Value("${smalllog.kafka.kafkaGroupName:logConsumer}")
    public String kafkaGroupName = "logConsumer";

    @Value("${smalllog.model:redis}")
    private String model;

    /**
     * 支持携带协议，如：http、https
     */
    @Value("${smalllog.es.esHosts:}")
    private String esHosts;
    /**
     * 信任自签证书
     * <p>默认：true
     */
    @Value("${smalllog.es.trustSelfSigned:true}")
    private boolean trustSelfSigned = true;
    /**
     * hostname验证
     * <p>默认：false
     */
    @Value("${smalllog.es.hostnameVerification:false}")
    private boolean hostnameVerification = false;
    @Value("${smalllog.es.indexType:}")
    private String indexType;

    @Value("${smalllog.es.userName:}")
    private String esUserName;
    @Value("${smalllog.es.passWord:}")
    private String esPassWord;
    @Value("${smalllog.es.shards:5}")
    private int shards;
    @Value("${smalllog.es.replicas:0}")
    private int replicas;
    @Value("${smalllog.es.maxShards:100000}")
    private Long maxShards;

    @Value("${smalllog.es.refresh.interval:10s}")
    private String refreshInterval;
    @Value("${smalllog.es.indexType.model:day}")
    private String indexTypeModel;
    @Value("${smalllog.es.indexType.zoneId:GMT+8}")
    private String indexTypeZoneId;


    @Value("${smalllog.redis.redisHost:}")
    private String redisHost;
    @Value("${smalllog.redis.redisPassWord:}")
    private String redisPassWord;
    @Value("${smalllog.redis.redisPort:6379}")
    private int redisPort;
    @Value("${smalllog.redis.redisDb:0}")
    private int redisDb = 0;

    @Value("${smalllog.queue.redis.redisHost:}")
    private String queueRedisHost;
    @Value("${smalllog.queue.redis.sentinel.masterName:}")
    private String queueRedisSentinelMasterName;
    @Value("${smalllog.queue.redis.redisPassWord:}")
    private String queueRedisPassWord;
    @Value("${smalllog.queue.redis.redisDb:0}")
    private int queueRedisDb = 0;

    @Value("${admin.log.keepDays:0}")
    private int keepDays;
    @Value("${admin.log.trace.keepDays:0}")
    private int traceKeepDays;

    @Value("${smalllog.lite.log.path:}")
    private String liteLogPath;

    @Bean(name = "redisClient")
    public AbstractClient initRedisClient() {
        String mgRedisHost = "";
        String mgRedisPassWord = "";
        String mgMasterName = "";
        int redisPort = 0;
        int mgRedisDb = 0;
        if (!StringUtils.isEmpty(this.redisHost)) {
            mgRedisHost = this.redisHost;
            mgRedisPassWord = this.redisPassWord;
            mgRedisDb = this.redisDb;
            redisPort = this.redisPort;
        } else {
            mgRedisHost = this.queueRedisHost;
            mgRedisPassWord = this.queueRedisPassWord;
            mgRedisDb = this.queueRedisDb;
        }
        logger.info("管理 redis host:{}", mgRedisHost);
        if (!StringUtils.isEmpty(mgRedisHost)) {
            return new RedisClient(mgRedisHost, redisPort, mgRedisPassWord, mgRedisDb);
        }
        logger.error("找不到redis配置项！请检查配置！");
        return null;
    }


    /**
     * 加载配置
     */
    private void loadConfig() {
        InitConfig.MAX_SEND_SIZE = this.maxSendSize;
        InitConfig.KAFKA_GROUP_NAME = this.kafkaGroupName;
        InitConfig.MAX_INTERVAL = this.interval;
        InitConfig.START_MODEL = this.model;

        InitConfig.ES_INDEX_SHARDS = this.shards;
        InitConfig.ES_INDEX_REPLICAS = this.replicas;
        InitConfig.ES_REFRESH_INTERVAL = this.refreshInterval;
        InitConfig.ES_INDEX_MODEL = this.indexTypeModel;
        if(this.liteLogPath!=null&&!"".equals(this.liteLogPath)){
            InitConfig.LITE_MODE_LOG_PATH=this.liteLogPath;
        }else {
            InitConfig.LITE_MODE_LOG_PATH=System.getProperty("user.dir");
        }

        try {
            ZoneId.of(this.indexTypeZoneId);
            InitConfig.ES_INDEX_ZONE_ID = this.indexTypeZoneId;
        } catch (Exception e) {
            logger.error("Please check config 'smalllog.es.indexType.zoneId', the value '{}' is invalid, use default value '{}'!",
                    this.indexTypeZoneId, InitConfig.ES_INDEX_ZONE_ID);
        }


        LogMessageConstant.ES_TYPE = this.indexType;


        InitConfig.keepDays = this.keepDays;
        InitConfig.traceKeepDays = this.traceKeepDays;
        InitConfig.maxShards=this.maxShards;

        logger.info("server run model:" + this.model);
        logger.info("maxSendSize:" + this.maxSendSize);
        logger.info("interval:" + this.interval);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        try {
            loadConfig();
            logger.info("load config success!");
        } catch (Exception e) {
            logger.error("smalllog load config success failed!", e);
        }
    }

    @Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();;
        return taskScheduler;
    }
}
